/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Engine.

    Maxsi Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiEngineContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiEngineContributors.h. For more information please see
	MaxsiEngineContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiEngine.dll
	A linkable version of Maxsi Engine

	MaxsiComDlg.cpp
	Common dialogs!

****************************************************************************/

#include "MaxsiEngine.h"
#include <commdlg.h>    // includes common dialog functionality
#include <dlgs.h>       // includes common dialog template defines
#include <cderr.h>      // includes the common dialog error codes

namespace MaxsiEngine
{
	MYDATA sMyData;			// an instance of a MYDATA
	UINT cdmsgShareViolation = 0;  // identifier from RegisterWindowMessage
	UINT cdmsgFileOK         = 0;  // identifier from RegisterWindowMessage
	UINT cdmsgHelp           = 0;  // identifier from RegisterWindowMessage

	LINK	char*	OpenFileDialogA(HINSTANCE Instance, HWND Owner, OPENFILENAMEA*	OpenFileName)
	{
		OPENFILENAMEA FallBackOpenFileName;
		char*	FileNameString	=	0;
		char*	WorkingDir		=	GetWorkingDirectory();
		char*	Result			=	0;
		if (!OpenFileName)
		{
			FileNameString		=	new char[MAX_PATH+1];
			FileNameString[0]	=	0;
			OpenFileName = &FallBackOpenFileName;
			OpenFileName->lStructSize		= sizeof(OPENFILENAMEA);
			OpenFileName->hwndOwner			= Owner;
			OpenFileName->hInstance			= GetModuleHandleA(NULL);
			OpenFileName->lpstrFilter		= NULL;
			OpenFileName->lpstrCustomFilter	= NULL;
			OpenFileName->nMaxCustFilter    = 0;
			OpenFileName->nFilterIndex      = 0;
			OpenFileName->lpstrFile         = FileNameString;
			OpenFileName->nMaxFile          = MAX_PATH;
			OpenFileName->lpstrFileTitle    = NULL;
			OpenFileName->nMaxFileTitle     = 0;
			OpenFileName->lpstrInitialDir   = WorkingDir;
			OpenFileName->lpstrTitle        = "Open a File";
			OpenFileName->nFileOffset       = 0;
			OpenFileName->nFileExtension    = 0;
			OpenFileName->lpstrDefExt       = NULL;
			OpenFileName->lCustData         = (LPARAM)&sMyData;
			OpenFileName->lpfnHook 		    = (LPOFNHOOKPROC)ComDlg32DlgProc;
			OpenFileName->lpTemplateName    = MAKEINTRESOURCEA(IDD_COMDLG32);
			OpenFileName->Flags             = OFN_SHOWHELP | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
		}

		if (GetOpenFileNameA(OpenFileName))
		{
			Result = BuildString(1,OpenFileName->lpstrFile);		
		}
		else
		{
			ProcessCDError(CommDlgExtendedError(), Owner );
		}
		delete[] FileNameString;
		return Result;
		return Result;
	}

	LINK	char*	SaveFileDialogA(HINSTANCE Instance, HWND Owner, OPENFILENAMEA*	OpenFileName)
	{
		OPENFILENAMEA FallBackOpenFileName;
		char*	FileNameString	=	0;
		char*	WorkingDir		=	GetWorkingDirectory();
		char*	Result			=	0;
		if (!OpenFileName)
		{
			FileNameString		=	new char[MAX_PATH+1];
			FileNameString[0]	=	0;
			OpenFileName = &FallBackOpenFileName;
			OpenFileName->lStructSize		= sizeof(OPENFILENAMEA);
			OpenFileName->hwndOwner			= Owner;
			OpenFileName->hInstance			= GetModuleHandleA(NULL);
			OpenFileName->lpstrFilter		= NULL;
			OpenFileName->lpstrCustomFilter	= NULL;
			OpenFileName->nMaxCustFilter    = 0;
			OpenFileName->nFilterIndex      = 0;
			OpenFileName->lpstrFile         = FileNameString;
			OpenFileName->nMaxFile          = MAX_PATH;
			OpenFileName->lpstrFileTitle    = NULL;
			OpenFileName->nMaxFileTitle     = 0;
			OpenFileName->lpstrInitialDir   = WorkingDir;
			OpenFileName->lpstrTitle        = "Save a File";
			OpenFileName->nFileOffset       = 0;
			OpenFileName->nFileExtension    = 0;
			OpenFileName->lpstrDefExt       = NULL;
			OpenFileName->lCustData         = (LPARAM)&sMyData;
			OpenFileName->lpfnHook 		    = (LPOFNHOOKPROC)ComDlg32DlgProc;
			OpenFileName->lpTemplateName    = MAKEINTRESOURCEA(IDD_COMDLG32);
			OpenFileName->Flags             = OFN_SHOWHELP | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
		}

		if (GetSaveFileNameA(OpenFileName))
		{
			Result = BuildString(1,OpenFileName->lpstrFile);		
		}
		else
		{
			ProcessCDError(CommDlgExtendedError(), Owner );
		}
		delete[] FileNameString;
		return Result;
		return Result;
	}

	BOOL NEAR PASCAL TestNotify(HWND hDlg, LPOFNOTIFYA pofn)
	{
		switch (pofn->hdr.code)
		{
			// The selection has changed. 
			case CDN_SELCHANGE:
			{
				char szFile[MAX_PATH];

				// Get the file specification from the common dialog.
				if ((size_t)CommDlg_OpenSave_GetSpec(GetParent(hDlg),
					szFile, sizeof(szFile)) <= sizeof(szFile))
				{
					// Set the dialog item to reflect this.
					SetDlgItemTextA(hDlg, IDE_SELECTED, szFile);
				}

				// Get the path of the selected file.
				if ((size_t)CommDlg_OpenSave_GetFilePath(GetParent(hDlg),
					szFile, sizeof(szFile)) <= sizeof(szFile))
				{
					// Display this path in the appropriate box.
					SetDlgItemTextA(hDlg, IDE_PATH, szFile);
				}
			}
			break;

			// A new folder has been opened.
			case CDN_FOLDERCHANGE:
			{
				char szFile[MAX_PATH];

				if ((size_t)CommDlg_OpenSave_GetFolderPath(GetParent(hDlg),
					szFile, sizeof(szFile)) <= sizeof(szFile))
				{
					// Display this new path in the appropriate box.
					SetDlgItemTextA(hDlg, IDE_SELECTED, szFile);
				}
			}
			break;

			// The "Help" pushbutton has been pressed.
			case CDN_HELP:
				MessageBoxA(hDlg, " No help is available.", "Maxsi Engine", MB_ICONERROR);
				break;

			// The 'OK' pushbutton has been pressed.
			case CDN_FILEOK:
				// Update the appropriate box.
				SetDlgItemTextA(hDlg,IDE_SELECTED, pofn->lpOFN->lpstrFile);
				SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 1L);
				break;

			// Received a sharing violation.
			case CDN_SHAREVIOLATION:
				// Update the appropriate box.
				SetDlgItemTextA(hDlg, IDE_SELECTED, pofn->pszFile);
				MessageBoxA(hDlg, "Sharing violation notify. This notification is not support by Maxsi Engine yet.", "Maxsi Engine", MB_OK);
				break;
		}

		return(TRUE);
	}

	//
	//   FUNCTION: ComDlg32DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
	//
	//  PURPOSE:  Processes messages for the File Open common dialog box.
	//
	//    MESSAGES:
	//
	//	WM_INITDIALOG - save pointer to the OPENFILENAME structure in User data
	//	WM_DESTROY - get the text entered and fill in the MyData structure
	//	WM_NOTIFY - pass this message onto the TestNotify function
	//	default - check for a sharing violation or the OK button and
	//    	display a message box.
	//
	//
	LRESULT CALLBACK ComDlg32DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
	{

		switch (uMsg)
		{
			case WM_INITDIALOG:
				// Save off the long pointer to the OPENFILENAME structure.
				SetWindowLongPtr(hDlg, DWLP_USER, (LONG)lParam);
				break;

			case WM_DESTROY:
				{
				LPOPENFILENAME lpOFN = (LPOPENFILENAME)GetWindowLongPtr(hDlg, DWLP_USER);
				LPMYDATA psMyData = (LPMYDATA)lpOFN->lCustData;

				GetDlgItemTextA(hDlg, IDE_PATH, psMyData->szTest1, sizeof(psMyData->szTest1));
				GetDlgItemTextA(hDlg, IDE_SELECTED, psMyData->szTest2, sizeof(psMyData->szTest2));
				}
				break;

			case WM_NOTIFY:
				TestNotify(hDlg, (LPOFNOTIFYA)lParam);

			default:
				if (uMsg == cdmsgFileOK)
				{
					SetDlgItemTextA(hDlg, IDE_SELECTED, ((LPOPENFILENAMEA)lParam)->lpstrFile);
					if (MessageBoxA(hDlg, "Got the OK button message.\n\nShould I open it?", "ComDlg32 Test", MB_YESNO)
						== IDNO)
					{
						SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 1L);
					}
					break;
				}
				else if (uMsg == cdmsgShareViolation)
				{
					SetDlgItemTextA(hDlg, IDE_SELECTED, (LPSTR)lParam);
					MessageBoxA(hDlg, "Got a sharing violation message.", "ComDlg32 Test", MB_OK);
					break;
				}
				return FALSE;
		}
		return TRUE;
	}

	void ProcessCDError(DWORD dwErrorCode, HWND hWnd)
	{
	   WORD  wStringID;
	   TCHAR  buf[MAX_PATH];

	   switch(dwErrorCode)
		  {
		 case CDERR_DIALOGFAILURE:   wStringID=IDS_DIALOGFAILURE;   break;
		 case CDERR_STRUCTSIZE:      wStringID=IDS_STRUCTSIZE;      break;
		 case CDERR_INITIALIZATION:  wStringID=IDS_INITIALIZATION;  break;
		 case CDERR_NOTEMPLATE:      wStringID=IDS_NOTEMPLATE;      break;
		 case CDERR_NOHINSTANCE:     wStringID=IDS_NOHINSTANCE;     break;
		 case CDERR_LOADSTRFAILURE:  wStringID=IDS_LOADSTRFAILURE;  break;
		 case CDERR_FINDRESFAILURE:  wStringID=IDS_FINDRESFAILURE;  break;
		 case CDERR_LOADRESFAILURE:  wStringID=IDS_LOADRESFAILURE;  break;
		 case CDERR_LOCKRESFAILURE:  wStringID=IDS_LOCKRESFAILURE;  break;
		 case CDERR_MEMALLOCFAILURE: wStringID=IDS_MEMALLOCFAILURE; break;
		 case CDERR_MEMLOCKFAILURE:  wStringID=IDS_MEMLOCKFAILURE;  break;
		 case CDERR_NOHOOK:          wStringID=IDS_NOHOOK;          break;
		 case PDERR_SETUPFAILURE:    wStringID=IDS_SETUPFAILURE;    break;
		 case PDERR_PARSEFAILURE:    wStringID=IDS_PARSEFAILURE;    break;
		 case PDERR_RETDEFFAILURE:   wStringID=IDS_RETDEFFAILURE;   break;
		 case PDERR_LOADDRVFAILURE:  wStringID=IDS_LOADDRVFAILURE;  break;
		 case PDERR_GETDEVMODEFAIL:  wStringID=IDS_GETDEVMODEFAIL;  break;
		 case PDERR_INITFAILURE:     wStringID=IDS_INITFAILURE;     break;
		 case PDERR_NODEVICES:       wStringID=IDS_NODEVICES;       break;
		 case PDERR_NODEFAULTPRN:    wStringID=IDS_NODEFAULTPRN;    break;
		 case PDERR_DNDMMISMATCH:    wStringID=IDS_DNDMMISMATCH;    break;
		 case PDERR_CREATEICFAILURE: wStringID=IDS_CREATEICFAILURE; break;
		 case PDERR_PRINTERNOTFOUND: wStringID=IDS_PRINTERNOTFOUND; break;
		 case CFERR_NOFONTS:         wStringID=IDS_NOFONTS;         break;
		 case FNERR_SUBCLASSFAILURE: wStringID=IDS_SUBCLASSFAILURE; break;
		 case FNERR_INVALIDFILENAME: wStringID=IDS_INVALIDFILENAME; break;
		 case FNERR_BUFFERTOOSMALL:  wStringID=IDS_BUFFERTOOSMALL;  break;

		 case 0:   //User may have hit CANCEL or we got a *very* random error
			return;

		 default:
			wStringID=IDS_UNKNOWNERROR;
		  }

	   LoadString(NULL, wStringID, buf, sizeof(buf));
	   MessageBox(hWnd, buf, NULL, MB_OK);
	   return;
	}
}
